<template>
  <div class="home" ref="containerRef"></div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
import { CatmullRomCurve3, Mesh, Object3D } from "three";

export default defineComponent({
  setup(props) {
    const containerRef = ref();
    let scene = new THREE.Scene();
    const draw = async () => {
      //   //绘制曲线
      let line1 = new THREE.LineCurve3(
          new THREE.Vector3(-80, 0, 0),
          new THREE.Vector3(200, 0, 0)
        ),
        line2 = new THREE.LineCurve3(
          new THREE.Vector3(200, 0, 0),
          new THREE.Vector3(200, 100, 0)
        ),
        line3 = new THREE.LineCurve3(
          new THREE.Vector3(200, 100, 0),
          new THREE.Vector3(500, 100, 0)
        ),
        curvePath = new THREE.CurvePath<THREE.Vector3>();
      curvePath.curves.push(line1, line2, line3);
      let curve = new THREE.CatmullRomCurve3(
        [
          new THREE.Vector3(-80, 0, 0),
          new THREE.Vector3(0, 0, 0),
          new THREE.Vector3(100, 0, 0),
          new THREE.Vector3(200, 0, 0),
          new THREE.Vector3(200, 50, 0),
          new THREE.Vector3(200, 100, 0),
          new THREE.Vector3(300, 100, 0),
          new THREE.Vector3(400, 100, 0),
          new THREE.Vector3(500, 100, 0),
        ],
        false,
        "catmullrom",
        0.1
      );
      // let points = curve.getSpacedPoints(200);
      let geometry = new THREE.TubeGeometry(curve, 100, 2, 50, false);
      //   geometry.setFromPoints(points);
      let material = new THREE.MeshPhongMaterial({
        color: 0x000000,
        transparent: true,
        opacity: 0.3,
      });
      let tube = new THREE.Mesh(geometry, material);
      scene.add(tube);
      //加载汽车
      let fbxLoader = new FBXLoader(),
        textureLoader = new THREE.TextureLoader();
      let carModel = await fbxLoader.loadAsync("/models/car/car.fbx"),
        picture = await textureLoader.loadAsync("/models/car/0.jpeg"),
        bumpPic = await textureLoader.loadAsync("/models/car/1.png");
      carModel.scale.set(0.03, 0.03, 0.03);
      carModel.position.set(-80, 0, 0);
      //   carModel.lookAt(points[i + 1].x, points[i + 1].y, points[i + 1].z);
      // carModel.rotateX(-Math.PI / 2);
      // carModel.rotateZ(Math.PI / 2);
      carModel.traverse((child: unknown) => {
        if (child instanceof THREE.Mesh) {
          let material = new THREE.MeshPhongMaterial({
            map: picture,
            specularMap: bumpPic,
            specular: 0xffffff,
            shininess: 100,
            side: THREE.DoubleSide,
          });
          child.material = material;
        }
      });
      let carModel1 = carModel.clone(true)
      carModel1.position.set(-100,0,0)
      scene.add(carModel);
      scene.add(carModel1)
      let axisHeler = new THREE.AxesHelper(300);
      scene.add(axisHeler);
      /**
       * 光源设置
       */
      //点光源
      let point = new THREE.PointLight(0xffffff);
      point.position.set(10, 50, 100); //点光源位置
      scene.add(point); //点光源添加到场景中
      //   环境光
      let ambient = new THREE.AmbientLight(0xffffff);
      scene.add(ambient);
      /**
       * 相机设置
       */
      let width = window.innerWidth; //窗口宽度
      let height = window.innerHeight; //窗口高度
      let k = width / height; //窗口宽高比
      let s = 200; //三维场景显示范围控制系数，系数越大，显示的范围越大
      //创建相机对象
      let camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
      camera.position.set(0, 0, 500); //设置相机位置
      camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
      /**
       * 创建渲染器对象
       */
      let renderer = new THREE.WebGLRenderer({
        antialias: true,
      });
      renderer.setSize(width, height - 91); //设置渲染区域尺寸
      renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
      containerRef.value.appendChild(renderer.domElement); //body元素中插入canvas对象
      //执行渲染操作   指定场景、相机作为参数
      function render() {
        console.log(111);
        
        renderer.render(scene, camera); //执行渲染操作
        // if (progress > 0.999) {
        //   return; //停留在管道末端,否则会一直跑到起点 循环再跑
        // }
        // requestAnimationFrame(render);
        // progress += 0.0009;
        // if (curve) {
        //   let point = curve.getPoint(progress);
        //   let point1 = curve.getPoint(progress + 0.001);
        //   if (point && point.x && point1 && point1.x) {
        //     carModel.position.set(point.x, point.y, point.z);
        //     carModel.lookAt(point1.x, point1.y, point1.z);
        //     carModel.rotateX(-Math.PI / 2);
        //     carModel.rotateY(-Math.PI / 2);
        //   }
        // }
      }
      let needRenderCount = 0,
        requestAnimationFrameId: number;
      function needRender() {
        needRenderCount++;
        if (!requestAnimationFrameId) {
          function execRender() {
            renderer.render(scene, camera); //执行渲染操作
            requestAnimationFrameId = requestAnimationFrame(execRender);
          }
          execRender();
        }
      }
      function cancelRender() {
        needRenderCount--;
        if (needRenderCount === 0) {
          cancelAnimationFrame(requestAnimationFrameId);
        }
      }
      function moveCar(car: Object3D, path: CatmullRomCurve3) {
        let progress = 0;
        function animation() {
          if (progress > 0.999) {
            cancelRender();
            return; //停留在管道末端,否则会一直跑到起点 循环再跑
          }
          progress += 0.0009;
          if (path) {
            let point = path.getPoint(progress);
            let point1 = path.getPoint(progress + 0.001);
            if (point && point.x && point1 && point1.x) {
              requestAnimationFrame(animation);
              car.position.set(point.x, point.y, point.z);
              car.lookAt(point1.x, point1.y, point1.z);
              car.rotateX(-Math.PI / 2);
              car.rotateY(-Math.PI / 2);
            }
          }
        }
        needRender();
        animation();
      }
      render();
      moveCar(carModel, curve);
      setTimeout(() => {
        moveCar(carModel1,curve)
      }, 1000);
      let controls = new OrbitControls(camera, renderer.domElement); //创建控件对象
      controls.addEventListener("change", render); //监听鼠标、键盘事件
    };
    onMounted(() => {
      draw();
    });
    return { containerRef };
  },
});
</script>
